package com.kjc.demo.basic.config;

import org.apache.http.client.HttpClient;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContextBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

 /**
  * @Author kangjichang
  * @Time 2018年5月3日 上午10:24:20
  * @Version 1.0
  * <p>Description:HttpClient4 配置，PoolingHttpClientConnectionManager 池化http连接</p>
  *
  */
@Configuration
public class RestTemplateConfig {
	private Logger logger = LoggerFactory.getLogger(this.getClass());

	@Primary
	@Bean
	public RestTemplate restTemplate(HttpClient httpClient) {
		HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
		//指建立连接的超时时间
		httpRequestFactory.setConnectionRequestTimeout(5 * 1000);
		//指从连接池获取到连接的超时时间，如果是非连接池的话，该参数暂时没有发现有什么用处
		httpRequestFactory.setConnectTimeout(3 * 1000);
		//读超时时间
		httpRequestFactory.setReadTimeout(30 * 1000);
		return new RestTemplate(httpRequestFactory);
	}
	


	@Bean
	public HttpClient httpClient() {
		try {
			HttpClientBuilder b = HttpClientBuilder.create();

			// setup a Trust Strategy that allows all certificates.
			//
			SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
				@Override
				public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
					return true;
				}
			}).build();
			b.setSSLContext(sslContext);

			// don't check Hostnames, either.
			// -- use SSLConnectionSocketFactory.getDefaultHostnameVerifier(), if you don't
			// want to weaken
			HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;

			// here's the special part:
			// -- need to create an SSL Socket Factory, to use our weakened "trust
			// strategy";
			// -- and create a Registry, to register it.
			//
			SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);

			Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
					.register("http", PlainConnectionSocketFactory.getSocketFactory())
					.register("https", sslSocketFactory).build();

			// now, we create connection-manager using our Registry.
			// -- allows multi-threaded use
			PoolingHttpClientConnectionManager connMgr = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
			connMgr.setMaxTotal(300);
			connMgr.setDefaultMaxPerRoute(60);
			b.setConnectionManager(connMgr);

			// finally, build the HttpClient;
			// -- done!
			CloseableHttpClient client = b.build();
			return client;
		} catch (Exception e) {
			logger.error("restTemplate 服务初始化失败：", e);
			throw new UnsupportedOperationException(e);
		}
	}

	@Bean
	public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
		return new PropertySourcesPlaceholderConfigurer();
	}

}
